//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2003-2007
// ALAN and ALAN Map 500 are registered trademarks of ALAN Group.
//
// ALAN Map 500 TLG (legacy) track parser.
//

# include "StdAfx.h"
# include "HoluxTlg.h"
# include "Map.h"
# include "Types.h"
# include "Load.h"
# include "Log.h"
# include "Status.h"
# include "ParseHelpers.h"
# include "Wrappers.h"
# include "Globals.h"

class CAlanTlgLoader : public CMapLoader {
  public:
	// Override.
	virtual bool IsValid (const char * _pData, size_t _cFileSize) const;
	virtual LoadStatus_t Load (const char * _pData, size_t _cFileSize, const char * _strFileName, map_t * _pMap);
};

DECLARE_WPTRK_LOADER (CAlanTlgLoader, "alan-tlg", "tlg", "ALAN Map 500 legacy tracks (*.tlg)", ftiTracks);

bool CAlanTlgLoader::IsValid (const char * _pData, size_t _cFileSize) const {
	if (_cFileSize < 0x20000 + sizeof (CTlgHdr))
		return false;

	if (reinterpret_cast<const CTlgHdr *> (_pData + 0x20000)->dwSignature == c_dwTlgSignature)
		return true;

	return false;
}

LoadStatus_t CAlanTlgLoader::Load (const char * _pData, size_t _cFileSize, const char * _strFileName, map_t * _pMap) {
	const char * const pEnd  = _pData + _cFileSize;

	file_refs_t file_refs;
	file_refs.push_back (file_ref_t ());
	file_refs.back ().strFileName = _strFileName;
	file_refs.back ().bAttachment = true;

	SetProgressStatus (0);

	const CTlgHdr      * const pHdr = reinterpret_cast<const CTlgHdr *> (_pData + 0x20000);
	const CTlgTrackLog * const pLogs [c_cTlgMaxTracks] = {
		reinterpret_cast<const CTlgTrackLog *> (_pData),
		reinterpret_cast<const CTlgTrackLog *> (_pData + sizeof (CTlgTrackLog)),
		reinterpret_cast<const CTlgTrackLog *> (_pData + sizeof (CTlgTrackLog)*2),
		reinterpret_cast<const CTlgTrackLog *> (_pData + 0x10000),
		reinterpret_cast<const CTlgTrackLog *> (_pData + 0x10000 + sizeof (CTlgTrackLog)),
	};

	// TODO: research.
	const int nDay    =   pHdr->dwDate        & 0xFF;
	const int nMonth  = ((pHdr->dwDate >> 8)  & 0xF);
	const int nYear   = ((pHdr->dwDate >> 12) & 0xF) + 1990;
	const int nSecond =  pHdr->dwTime        & 0x3F;
	const int nMinute = (pHdr->dwTime >> 8)  & 0x3F;
	const int nHour   = (pHdr->dwTime >> 14) & 0x1F;
	ReportText ("* Date: %02d-%02d-%04d", nDay, nMonth, nYear);
	ReportText ("* Time: %02d:%02d:%02d", nHour, nMinute, nSecond);

	for (size_t cTrack = 0; /*cTrack < pHdr->wTracks &&*/ cTrack < c_cTlgMaxTracks; ++ cTrack) {
		const CTlgTrack & track = pHdr->tracks [cTrack];
		if (track.dwOccupied == 0)
			continue;

		const CTlgTrackLog & log = * (pLogs [cTrack]);

		//
		// Create track.
		//
		rgn_t & rgn = _pMap->CreateRgn (rkPolyline);
		rgn.SetTrackType ();

		rgn.pFileRef = & file_refs.back ();
		rgn.cBeginPos = reinterpret_cast<const char *> (& log) - _pData;
		rgn.cEndPos = pEnd - _pData;
		rgn.cFileLine = -1;

		rgn.strLabel.assign   (track.strName);
		rgn.strComment.assign (track.strComment, GetLineLen (track.strComment, track.strComment + sizeof (track.strComment) - 1));

		rgn.elements.push_back (rgn_element_t ());
		rgn_element_t & element = rgn.elements.back ();
		element.cLevel = 0;
		element.cFileOffset = rgn.cBeginPos;

		points_t & points = element.points;
		points.resize (track.wPoints);
		for (size_t cPoint = 0; cPoint < track.wPoints && cPoint < c_cTlgMaxPoints; ++ cPoint) {
			const CTlgPoint & pt = log.points [cPoint];
			point_t & point = points [cPoint];

			point.x =  pt.lX/36000.f;
			point.y = -pt.lY/36000.f;
		}

		rgn.pExtra->wtr.CreateTrack ();

		SetProgressStatus (50*cTrack/c_cTlgMaxTracks);
	}
	// TODO:

	_pMap->file_refs.swap (file_refs);

	// Suppress warning about empty Zoom etc.
	_pMap->bNoHeader = true;
	_pMap->cHeaderLen = 0;

	SetProgressStatus (50);

	return lsOK;
}
